package edu.gatech.cs2340.mule.view;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.border.LineBorder;

import edu.gatech.cs2340.mule.model.Player;
import edu.gatech.cs2340.mule.presenter.MuleGamePresenter;

import java.awt.Color;
import java.awt.Point;
import java.awt.event.ActionListener;
import java.util.Collection;

/**
 * This panel holds the grid of buttons that resemble the various different
 * map tiles. The class can add images and listeners to the buttons is contains
 * as well.
 * 
 * @author Zach Elliott
 */
public class MapPanel extends JPanel {
	
	private static final int NUM_OF_COLS = 9;
	private static final int NUM_OF_ROWS = 5;
	
	private JButton[][] mapButtons;
	
	/**
	 * Create the panel. Add the buttons to the grid.
	 */
	public MapPanel() {
		mapButtons = new JButton[NUM_OF_ROWS][NUM_OF_COLS];
		setLayout(new GridLayout(NUM_OF_ROWS, NUM_OF_COLS));
		setBackground(MuleGamePresenter.BACKGROUND_COLOR);
		for(int i = 0; i < NUM_OF_ROWS; i++) {
			for(int j = 0; j < NUM_OF_COLS; j++) {
				mapButtons[i][j] = new JButton();
				mapButtons[i][j].setBackground(MuleGamePresenter.BACKGROUND_COLOR);
				mapButtons[i][j].setBorder(new LineBorder(MuleGamePresenter.BACKGROUND_COLOR, 1));
				add(mapButtons[i][j]);
			}
		}
	}
	
	/**
	 * Adds the image to the button
	 * 
	 * @param i The row of the image to be added
	 * @param j The column of the image to be added
	 * @param sourceName The file path for the image
	 */
	public void addImageToButton(int i, int j, String sourceName) {
		mapButtons[i][j].setIcon(new ImageIcon(sourceName));
		mapButtons[i][j].setDisabledIcon(new ImageIcon(sourceName));
	}
	
	/**
	 * Adds actionListeners to all the buttons
	 * 
	 * @param a The action listener to be added to the buttons
	 */
	public void addListenersToGrid(ActionListener a) {
		for(int i = 0; i < NUM_OF_ROWS; i++) {
			for(int j = 0; j < NUM_OF_COLS; j++) {
				mapButtons[i][j].addActionListener(a);
			}
		}
	}
	
	/**
	 * Returns a Point based on the button's location in the 2d array
	 * 
	 * @param button The button to get the location of
	 * @return A point object representing the location of the button on the map
	 */
	public Point getButtonPoint(JButton button) {
		for(int i = 0; i < NUM_OF_ROWS; i++) {
			for(int j = 0; j < NUM_OF_COLS; j++) {
				if(mapButtons[i][j].equals(button)) {
					return new Point(i,j);
				}
			}
		}
		return null; //if the button is not on the grid
	}
	
	/**
	 * Disables all buttons so that they cannot be clicked
	 */
	public void disableMap() {
		for(int i = 0; i < NUM_OF_ROWS; i++) {
			for(int j = 0; j < NUM_OF_COLS; j++) {
				mapButtons[i][j].setEnabled(false);
			}
		}
	}
	
	/**
	 * Enables all buttons so that they can be clicked
	 */
	public void enableMap() {
		for(int i = 0; i < NUM_OF_ROWS; i++) {
			for(int j = 0; j < NUM_OF_COLS; j++) {
				mapButtons[i][j].setEnabled(true);
			}
		}
	}
	
	/**
	 * Enables all specified buttons so that they can be clicked
	 */
	public void enableButtons(Collection<Point> mapTiles) {
		for(Point p : mapTiles) {
			mapButtons[(int) p.getX()][(int) p.getY()].setEnabled(true);
		}
	}
	
	/**
	 * Disables all specified buttons so that they cannot be clicked
	 */
	public void disableButtons(Collection<Point> mapTiles) {
		for(Point p : mapTiles) {
			mapButtons[(int) p.getX()][(int) p.getY()].setEnabled(false);
		}
	}
	
	/**
	 * Updates the button's border based on the player's color
	 * 
	 * @param p The point to update the border of 
	 * @param currentPlayer The current player who is taking a turn
	 */
	public void updateButtonColor(Point p, Player currentPlayer) {
		for(int i = 0; i < NUM_OF_ROWS; i++) {
			for(int j = 0; j < NUM_OF_COLS; j++) {
				if(p.getX() == i && p.getY() == j) {
					Color c = currentPlayer.getPlayerColor();
					mapButtons[i][j].setBorder(new LineBorder(c, 10));
				}
			}
		}
	}
}
